<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Acconeer API: /home/ai/jenkins/workspace/sw-main@2/doc/user_guides/rss/iq.md Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">Acconeer API
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('iq_8md.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">/home/ai/jenkins/workspace/sw-main@2/doc/user_guides/rss/iq.md</div>  </div>
</div><!--header-->
<div class="contents">
<a href="iq_8md.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;# IQ Service {#iq}</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;The IQ Service is one of four services that provide an interface for reading out the radar signal from the Acconeer A111 sensor. The IQ-data can be seen as an extension of the Envelope data. In addition to the amplitude, the IQ data also includes information on the phase of the radar signal. The data returned from the IQ Service is represented as complex numbers and the IQ data is typically further processed using various signal processing algorithms. The IQ data can for example be used for measurement of small changes in distance with micrometer accuracy or for efficient background cancellation.</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;For applications where the phase information is not needed you may consider using the Envelope service or Power Bins service instead. They both provide amplitude data and are easier to understand and work with compared to the IQ Service. The Envelope service provides full resolution, whereas the power bins interface provides less processed subsampled amplitude data.</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;![](RSS_stack.png)</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;Before using the IQ service, we recommend that you have a basic understanding of complex numbers and how they are used to represent phase and amplitude in signal processing.</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;Acconeer provide an example of how to use the IQ service: example_service_iq.c</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;For more details on the IQ data it is recommended to use our exploration tool. Check it out on [github](https://github.com/acconeer/acconeer-python-exploration), https://github.com/acconeer/acconeer-python-exploration.</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;## Disclaimer</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;Profile 3-5 will not have optimal performance using A111 with batch number 10467, 10457 or 10178 (also when mounted on XR111 and XR112). XM112 and XM122 are not affected since they have A111 from other batches.</div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;</div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;# Setting up the Service</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;## Initializing the System</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;The Radar System Software (RSS) must be activated before any other calls are done. The activation requires a pointer to an acc_hal_t  struct which contains information on the hardware integration and function pointers to hardware driver functions that are needed by RSS. See chapter 4 in the document “HAL  Integration User Guide” for more information on how to integrate to the driver layer and populate the hal struct.</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;In Acconeer’s example integration towards STM32 and the drivers generated by the STM32Cube tool, there is a function acc_hal_integration_get_implementation to obtain the hal struct.</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;```c</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;acc_hal_t hal = acc_hal_integration_get_implementation();</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;if (!acc_rss_activate(&amp;hal))</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;{</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;   /* Handle error */</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;}</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;```</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;The corresponding code looks slightly different in software packages for the Raspberry Pi and other software packages from Acconeer where peripheral drivers for the host are included. The driver layer is first initialized by calling acc_driver_hal_init. The hal struct is then obtained with the function acc_driver_hal_get_implementation.</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;```c</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;if (!acc_driver_hal_init())</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;{</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;   /* Handle error */</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;}</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;hal = acc_driver_hal_get_implementation();</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;if (!acc_rss_activate(&amp;hal))</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;{</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;   /* Handle error */</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;}</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;```</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;## Service API</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;All services in the Acconeer API are created and activated in two distinct steps. In the first creation step the configuration settings are evaluated and all necessary resources are allocated. If there is some error in the configuration or if there are not enough resources in the system to run the service, the creation step will fail. However, when the creation is successful you can be sure that the second activation step will not fail due to any configuration or resource issues. When the service is activated the radar is activated and the radar data starts to flow from the sensor to the application.</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;## IQ Service Configuration</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;Before the IQ service can be created and activated, we must prepare a service configuration. First a configuration is created.</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;```c</div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;acc_service_configuration_t iq_configuration = acc_service_iq_configuration_create();</div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;if (iq_configuration == NULL)</div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;{</div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;   /* Handle error */</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;}</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;```</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;The newly created service configuration contains default settings for all configuration parameters and can be passed directly to the acc_service_create function. However, in most scenarios there is a need to change at least some of the configuration parameters. See acc_service_iq.h and acc_base_configuration.h for a complete description of configuration parameters.</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;### Profiles</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;The services and detectors support profiles with different configuration of emission in the sensor. The different profiles provide an option to configure the wavelet length and optimize on either depth resolution or radar loop gain. More information regarding profiles can be read in the [sensor introduction document](https://acconeer-python-exploration.readthedocs.io/en/latest/sensor_introduction.html), https://acconeer-python-exploration.readthedocs.io/en/latest/sensor_introduction.html.</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;![](fig_distance_resolution.png)</div><div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;</div><div class="line"><a name="l00077"></a><span class="lineno">   77</span>&#160;The figure above shows the Envelope signal of the same objects with two different profiles, one with short wavelet and one with longer.</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;The IQ service supports 5 different profiles which are defined in acc_service.h. Profile 1 has the shortest wavelet and should be used in applications which aim to see multiple objects or with short distance to the object. Profiles with higher numbers have longer wavelets and are more suitable to use in applications which aim to see objects with weak reflection or objects further away from the sensor. The highest profiles, 4 and 5, are optimized for maximum radar loop gain which leads to lower precision in the distance estimate. It is recommended to start using profile 2 and 3. Profile 1, 4 and 5 are not yet optimized for all configurations for the IQ service.</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;</div><div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;Profiles can be configured by the application by using a set function in the service api. The default profile is ACC_SERVICE_PROFILE_2.</div><div class="line"><a name="l00082"></a><span class="lineno">   82</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;```c</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;void acc_service_profile_set(acc_service_configuration_t service_configuration,</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;                             acc_service_profile_t       profile);</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;```</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;### Repetition Mode</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;RSS supports two different repetition modes which configure the control flow of the sensor when it&#39;s producing data. In both modes, the application initiates the data transfer from the sensor and is responsible to keep the timing by fetching data from the service. The repetition modes are called on_demand and streaming and the default mode is on_demand.</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;Repetition mode on_demand lets the application decide when the sensor produces data. This mode is recommended to be used if the application is not dependent of a fixed update rate and it&#39;s more important for the application to control the timing. An example could be if the application requests data at irregular time or with low frequency and it&#39;s more important to enable low power consumption. Repetition mode on_demand should also be used if the application set a length which requires stitching or want to use power save mode off.</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;</div><div class="line"><a name="l00094"></a><span class="lineno">   94</span>&#160;```c</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;void acc_base_configuration_repetition_mode_on_demand_set(acc_base_configuration_t configuration);</div><div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;```</div><div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;Repetition mode streaming configures the sensor to produce data based on a hardware timer which is very accurate. It is recommended to use repetition mode streaming if the application requires very accurate timing. An example could be if the data should be processed with a fft. This mode can not be used it the application set a length which requires stitching.</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;```c</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;void acc_base_configuration_repetition_mode_streaming_set(acc_base_configuration_t configuration, float update_rate);</div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;```</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;</div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;### Output Data Format</div><div class="line"><a name="l00105"></a><span class="lineno">  105</span>&#160;</div><div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;The IQ service have an option to provide two different types of output format, int16 complex and float complex. The default output type is int16 complex and the type can be changed with a configuration function.</div><div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;```c</div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;typedef enum</div><div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;{</div><div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;   ACC_SERVICE_IQ_OUTPUT_FORMAT_FLOAT_COMPLEX, // The output format is float complex</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;   ACC_SERVICE_IQ_OUTPUT_FORMAT_INT16_COMPLEX  // The output format is acc_int16_complex_t</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;} acc_service_iq_output_format_enum_t;</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;typedef uint32_t acc_service_iq_output_format_t;</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00116"></a><span class="lineno">  116</span>&#160;void acc_service_iq_output_format_set(acc_service_configuration_t    service_configuration,</div><div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;                                      acc_service_iq_output_format_t format);</div><div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;```</div><div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;## Creating Service</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;</div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;After the IQ configuration has been prepared and populated with desired configuration parameters, the actual IQ service instance must be created. During the creation step all configuration parameters are validated and the resources needed by RSS are reserved. This means that if the creation step is successful, we can be sure that it is possible to activate the service and get data from the sensor (unless there is some unexpected hardware error).</div><div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;</div><div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;```c</div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;acc_service_handle_t handle = acc_service_create(iq_configuration);</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;if (handle == NULL)</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;{</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;   /* Handle error */</div><div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;}</div><div class="line"><a name="l00131"></a><span class="lineno">  131</span>&#160;```</div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;During service create, the service run a calibration sequence on the sensor. The calibration is used once at create and can be used until the service is destroyed. A new calibration is needed if the environment is changed, such as deviation in temperature.</div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;</div><div class="line"><a name="l00135"></a><span class="lineno">  135</span>&#160;If the service handle returned from acc_service_create is equal to NULL, then some setting in the configuration made it impossible for the system to create the service. One common reason is that the requested sweep length is too long or if the calibration fail, but in general, looking for error messages in the log is the best way to find out why a service creation failed.</div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;</div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;When the service has been created it is possible to get the actual number of samples (data_length) we will get for each sweep. This value can be useful when allocating buffers for storing the IQ data.</div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;</div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;```c</div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;acc_service_iq_metadata_t iq_metadata;</div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;acc_service_iq_get_metadata(handle, &amp;iq_metadata);</div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;</div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;uint16_t data[iq_metadata.data_length];</div><div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;```</div><div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;</div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;It is now also possible to activate the service. This means that the radar sensor starts to do measurements.</div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;```c</div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;if (!acc_service_activate(handle))</div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;{</div><div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;   /* Handle error */</div><div class="line"><a name="l00152"></a><span class="lineno">  152</span>&#160;}</div><div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;```</div><div class="line"><a name="l00154"></a><span class="lineno">  154</span>&#160;</div><div class="line"><a name="l00155"></a><span class="lineno">  155</span>&#160;## Reading IQ Data from the Sensor</div><div class="line"><a name="l00156"></a><span class="lineno">  156</span>&#160;</div><div class="line"><a name="l00157"></a><span class="lineno">  157</span>&#160;IQ data is read from the sensor by a call to the function acc_service_iq_get_next.  This function blocks until the next sweep arrives from the sensor and the IQ data is then copied to the IQ_data array.</div><div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;</div><div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;```c</div><div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;uint16_t                           data[iq_metadata.data_length];</div><div class="line"><a name="l00161"></a><span class="lineno">  161</span>&#160;acc_service_iq_result_info_t result_info;</div><div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;for (int i = 0; i &lt; 10; i++)</div><div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;{</div><div class="line"><a name="l00165"></a><span class="lineno">  165</span>&#160;   if (!acc_service_iq_get_next(handle, data, iq_metadata.data_length, &amp;result_info))</div><div class="line"><a name="l00166"></a><span class="lineno">  166</span>&#160;   {</div><div class="line"><a name="l00167"></a><span class="lineno">  167</span>&#160;           /* Handle error */</div><div class="line"><a name="l00168"></a><span class="lineno">  168</span>&#160;   }</div><div class="line"><a name="l00169"></a><span class="lineno">  169</span>&#160;}</div><div class="line"><a name="l00170"></a><span class="lineno">  170</span>&#160;```</div><div class="line"><a name="l00171"></a><span class="lineno">  171</span>&#160;</div><div class="line"><a name="l00172"></a><span class="lineno">  172</span>&#160;## Deactivating and Destroying the Service</div><div class="line"><a name="l00173"></a><span class="lineno">  173</span>&#160;</div><div class="line"><a name="l00174"></a><span class="lineno">  174</span>&#160;Call the acc_service_deactivate function to stop measurements.</div><div class="line"><a name="l00175"></a><span class="lineno">  175</span>&#160;</div><div class="line"><a name="l00176"></a><span class="lineno">  176</span>&#160;```c</div><div class="line"><a name="l00177"></a><span class="lineno">  177</span>&#160;if (!acc_service_deactivate(handle))</div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;{</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;   /* Handle error */</div><div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;}</div><div class="line"><a name="l00181"></a><span class="lineno">  181</span>&#160;```</div><div class="line"><a name="l00182"></a><span class="lineno">  182</span>&#160;</div><div class="line"><a name="l00183"></a><span class="lineno">  183</span>&#160;After the service has been deactivated it can be activated again to resume measurements or it can be destroyed to free up the resources associated with the service handle.</div><div class="line"><a name="l00184"></a><span class="lineno">  184</span>&#160;</div><div class="line"><a name="l00185"></a><span class="lineno">  185</span>&#160;```c</div><div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;acc_service_destroy(&amp;handle);</div><div class="line"><a name="l00187"></a><span class="lineno">  187</span>&#160;```</div><div class="line"><a name="l00188"></a><span class="lineno">  188</span>&#160;</div><div class="line"><a name="l00189"></a><span class="lineno">  189</span>&#160;Finally, call acc_rss_deactivate when the application doesn’t need to access the Radar System Software anymore. This releases any remaining resources allocated in RSS.</div><div class="line"><a name="l00190"></a><span class="lineno">  190</span>&#160;</div><div class="line"><a name="l00191"></a><span class="lineno">  191</span>&#160;```c</div><div class="line"><a name="l00192"></a><span class="lineno">  192</span>&#160;acc_rss_deactivate();</div><div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;```</div><div class="line"><a name="l00194"></a><span class="lineno">  194</span>&#160;</div><div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;# How to Interpret the IQ Data</div><div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;## Calculating Amplitude and Phase</div><div class="line"><a name="l00198"></a><span class="lineno">  198</span>&#160;</div><div class="line"><a name="l00199"></a><span class="lineno">  199</span>&#160;Each IQ data sample is a complex number consisting of two parts, a real component and an imaginary component. All complex numbers can be written in the form a + bi, where a and b are two ordinary real numbers and i is the imaginary unit that can be thought of having the value sqrt(-1). A complex number z = a + bi is said to have the real part a and the imaginary part b.</div><div class="line"><a name="l00200"></a><span class="lineno">  200</span>&#160;</div><div class="line"><a name="l00201"></a><span class="lineno">  201</span>&#160;Complex numbers can also be seen as points or vectors in the complex plane and be represented in polar coordinates with a radius and an angle. In the context of IQ data, the radius corresponds to the signal amplitude and angle is the phase of the signal.</div><div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;</div><div class="line"><a name="l00203"></a><span class="lineno">  203</span>&#160;![](iq.png)</div><div class="line"><a name="l00204"></a><span class="lineno">  204</span>&#160;</div><div class="line"><a name="l00205"></a><span class="lineno">  205</span>&#160;The Acconeer IQ data API rely on the c99 representation of complex float. Use the functions crealf and cimagf to extract the real and imaginary parts of the complex number.</div><div class="line"><a name="l00206"></a><span class="lineno">  206</span>&#160;</div><div class="line"><a name="l00207"></a><span class="lineno">  207</span>&#160;```c</div><div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;#include &lt;complex.h&gt;</div><div class="line"><a name="l00209"></a><span class="lineno">  209</span>&#160;</div><div class="line"><a name="l00210"></a><span class="lineno">  210</span>&#160;float complex z = 2 + 3*I;</div><div class="line"><a name="l00211"></a><span class="lineno">  211</span>&#160;</div><div class="line"><a name="l00212"></a><span class="lineno">  212</span>&#160;float a = crealf(z);</div><div class="line"><a name="l00213"></a><span class="lineno">  213</span>&#160;float b = cimagf(z);</div><div class="line"><a name="l00214"></a><span class="lineno">  214</span>&#160;</div><div class="line"><a name="l00215"></a><span class="lineno">  215</span>&#160;float amplitude = cabsf(z); // same as sqrtf(a*a + b*b)</div><div class="line"><a name="l00216"></a><span class="lineno">  216</span>&#160;float phase = cargf(z);     // same as atan2f(b,a)</div><div class="line"><a name="l00217"></a><span class="lineno">  217</span>&#160;```</div><div class="line"><a name="l00218"></a><span class="lineno">  218</span>&#160;</div><div class="line"><a name="l00219"></a><span class="lineno">  219</span>&#160;The phase difference between two IQ data samples z1 and z2 can be calculated using the expression cargf(z2 * conjf(z1)).</div><div class="line"><a name="l00220"></a><span class="lineno">  220</span>&#160;</div><div class="line"><a name="l00221"></a><span class="lineno">  221</span>&#160;```c</div><div class="line"><a name="l00222"></a><span class="lineno">  222</span>&#160;float phase_shift = cargf(z2 * conjf(z1));</div><div class="line"><a name="l00223"></a><span class="lineno">  223</span>&#160;```</div><div class="line"><a name="l00224"></a><span class="lineno">  224</span>&#160;</div><div class="line"><a name="l00225"></a><span class="lineno">  225</span>&#160;## Plotting Amplitude and Phase</div><div class="line"><a name="l00226"></a><span class="lineno">  226</span>&#160;</div><div class="line"><a name="l00227"></a><span class="lineno">  227</span>&#160;The graphs below show the amplitude and phase response from an object placed about 28 cm from the sensor. In the amplitude graph we can see shadow reflections 6 and 12 cm behind the object. To achieve as stable phase as possible, we are running the A111 radar sensor in a different mode in the IQ Service compared to the Envelope and Power Bins services. The phase gets more stable in the IQ service but as a side effect we are getting shadow reflections behind the object.</div><div class="line"><a name="l00228"></a><span class="lineno">  228</span>&#160;</div><div class="line"><a name="l00229"></a><span class="lineno">  229</span>&#160;![](iq_2.png)</div><div class="line"><a name="l00230"></a><span class="lineno">  230</span>&#160;</div><div class="line"><a name="l00231"></a><span class="lineno">  231</span>&#160;Note that in the phase plot below, the signal wraps around from pi to -pi at a distance around 0.30m and then it goes back from -pi to pi a little bit later.</div><div class="line"><a name="l00232"></a><span class="lineno">  232</span>&#160;</div><div class="line"><a name="l00233"></a><span class="lineno">  233</span>&#160;![](iq_3.png)</div><div class="line"><a name="l00234"></a><span class="lineno">  234</span>&#160;</div><div class="line"><a name="l00235"></a><span class="lineno">  235</span>&#160;## IQ Metadata</div><div class="line"><a name="l00236"></a><span class="lineno">  236</span>&#160;</div><div class="line"><a name="l00237"></a><span class="lineno">  237</span>&#160;In addition to the array with IQ data samples, a metadata data structure provides side information that can be useful when interpreting the IQ data. This metadata can be retrieved after creating the service. It will not change during operation, so it is only needed to be retrieved once for the created service.</div><div class="line"><a name="l00238"></a><span class="lineno">  238</span>&#160;</div><div class="line"><a name="l00239"></a><span class="lineno">  239</span>&#160;```c</div><div class="line"><a name="l00240"></a><span class="lineno">  240</span>&#160;acc_service_iq_metadata_t iq_metadata;</div><div class="line"><a name="l00241"></a><span class="lineno">  241</span>&#160;acc_service_iq_get_metadata(handle, &amp;iq_metadata);</div><div class="line"><a name="l00242"></a><span class="lineno">  242</span>&#160;```</div><div class="line"><a name="l00243"></a><span class="lineno">  243</span>&#160;</div><div class="line"><a name="l00244"></a><span class="lineno">  244</span>&#160;The most important member variable in the meta data structure is data_length which holds the length of the IQ data array. For other member variables see acc_service_iq_metadata_t.</div><div class="line"><a name="l00245"></a><span class="lineno">  245</span>&#160;</div><div class="line"><a name="l00246"></a><span class="lineno">  246</span>&#160;## IQ Result Info</div><div class="line"><a name="l00247"></a><span class="lineno">  247</span>&#160;</div><div class="line"><a name="l00248"></a><span class="lineno">  248</span>&#160;Result info is another kind of metadata which might change for each retrieved result. Result info is provided at the same time as the resulting array, either when calling get_next() or when a callback is triggered.</div><div class="line"><a name="l00249"></a><span class="lineno">  249</span>&#160;</div><div class="line"><a name="l00250"></a><span class="lineno">  250</span>&#160;```c</div><div class="line"><a name="l00251"></a><span class="lineno">  251</span>&#160;acc_service_iq_result_info_t result_info;</div><div class="line"><a name="l00252"></a><span class="lineno">  252</span>&#160;acc_service_iq_get_next(handle, data, data_length, &amp;result_info);</div><div class="line"><a name="l00253"></a><span class="lineno">  253</span>&#160;```</div><div class="line"><a name="l00254"></a><span class="lineno">  254</span>&#160;</div><div class="line"><a name="l00255"></a><span class="lineno">  255</span>&#160;The most important member variable is the sensor_communication_error which indicates whether a sensor communication has occurred. For other member variables see acc_service_iq_result_info_t</div><div class="line"><a name="l00256"></a><span class="lineno">  256</span>&#160;</div><div class="line"><a name="l00257"></a><span class="lineno">  257</span>&#160;## Micro Motion Measurement Example</div><div class="line"><a name="l00258"></a><span class="lineno">  258</span>&#160;</div><div class="line"><a name="l00259"></a><span class="lineno">  259</span>&#160;In this example we will implement a simple phase tracking algorithm that can detect micro motions about 25 cm from the sensor. It will look at differences in the phase information between consecutive sweeps and from that calculate how much the object has moved.</div><div class="line"><a name="l00260"></a><span class="lineno">  260</span>&#160;For each sweep we will look at one sample in the middle of the sweep array so the sweep length can be decreased to a few centimeters.  A short sweep range also means that we can run at a high sweep frequency. That is good, because between two sweeps, we can only measure phase differences up to pi radians – which corresponds to object movements of up to 1.25mm.</div><div class="line"><a name="l00261"></a><span class="lineno">  261</span>&#160;</div><div class="line"><a name="l00262"></a><span class="lineno">  262</span>&#160;```c</div><div class="line"><a name="l00263"></a><span class="lineno">  263</span>&#160;/* Set up the IQ service as described in chapter 2 and 3, use the configuration below */</div><div class="line"><a name="l00264"></a><span class="lineno">  264</span>&#160;</div><div class="line"><a name="l00265"></a><span class="lineno">  265</span>&#160;float frequencey = 300;</div><div class="line"><a name="l00266"></a><span class="lineno">  266</span>&#160;acc_base_configuration_requested_start_set(base_configuration, 0.2);</div><div class="line"><a name="l00267"></a><span class="lineno">  267</span>&#160;acc_base_configuration_requested_length_set(base_configuration, 0.4);</div><div class="line"><a name="l00268"></a><span class="lineno">  268</span>&#160;acc_base_configuration_repetition_mode_streaming_set(base_configuration, frequencey);</div><div class="line"><a name="l00269"></a><span class="lineno">  269</span>&#160;</div><div class="line"><a name="l00270"></a><span class="lineno">  270</span>&#160;```</div><div class="line"><a name="l00271"></a><span class="lineno">  271</span>&#160;</div><div class="line"><a name="l00272"></a><span class="lineno">  272</span>&#160;The IQ data sample from the previous sweep is stored in the variable z0 and the sample from the current sweep is stored in z1. The phase difference between the two sweeps is then calculated and we will get the movement between the sweeps by multiplying by wavelength / (4 * pi).</div><div class="line"><a name="l00273"></a><span class="lineno">  273</span>&#160;The variable acc_dist holds the accumulated distance changes since start of tracking. If the amplitude falls under the threshold the accumulated distance is reset to 0. Note that we are tracking relative movements about 25 cm from the sensor, wo do not measure any absolute distances in this example.</div><div class="line"><a name="l00274"></a><span class="lineno">  274</span>&#160;</div><div class="line"><a name="l00275"></a><span class="lineno">  275</span>&#160;```c</div><div class="line"><a name="l00276"></a><span class="lineno">  276</span>&#160;const float wavelength = 5.0; // wavelength in mm</div><div class="line"><a name="l00277"></a><span class="lineno">  277</span>&#160;const float pi = 3.14159265359;</div><div class="line"><a name="l00278"></a><span class="lineno">  278</span>&#160;const float amplitude_threshold = 0.1;</div><div class="line"><a name="l00279"></a><span class="lineno">  279</span>&#160;float complex z0 = 0;</div><div class="line"><a name="l00280"></a><span class="lineno">  280</span>&#160;float acc_dist = 0;</div><div class="line"><a name="l00281"></a><span class="lineno">  281</span>&#160;bool status;</div><div class="line"><a name="l00282"></a><span class="lineno">  282</span>&#160;</div><div class="line"><a name="l00283"></a><span class="lineno">  283</span>&#160;while (true) {</div><div class="line"><a name="l00284"></a><span class="lineno">  284</span>&#160;    status = acc_service_iq_get_next(iq_handle, iq_data, iq_metadata.data_length,</div><div class="line"><a name="l00285"></a><span class="lineno">  285</span>&#160;                                     &amp;result_info);</div><div class="line"><a name="l00286"></a><span class="lineno">  286</span>&#160;    if (!status) {</div><div class="line"><a name="l00287"></a><span class="lineno">  287</span>&#160;        /* handle error */</div><div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;    }</div><div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;</div><div class="line"><a name="l00290"></a><span class="lineno">  290</span>&#160;    float complex z1 = iq_data[iq_metadata.data_length/2];</div><div class="line"><a name="l00291"></a><span class="lineno">  291</span>&#160;</div><div class="line"><a name="l00292"></a><span class="lineno">  292</span>&#160;    if (cabsf(z1) &gt; amplitude_threshold) {</div><div class="line"><a name="l00293"></a><span class="lineno">  293</span>&#160;        if( z0 != 0) {</div><div class="line"><a name="l00294"></a><span class="lineno">  294</span>&#160;            float delta_dist = cargf(z1 * conjf(z0)) * wavelength / (4 * pi);</div><div class="line"><a name="l00295"></a><span class="lineno">  295</span>&#160;            acc_dist += delta_dist;</div><div class="line"><a name="l00296"></a><span class="lineno">  296</span>&#160;            printf(&quot;delta distance % 0.2f mm, accumulated distance % 0.2f mm, speed = &quot;</div><div class="line"><a name="l00297"></a><span class="lineno">  297</span>&#160;                   &quot;% 0.2f m/s\n&quot;, delta_dist, acc_dist, delta_dist * frequencey /1000);</div><div class="line"><a name="l00298"></a><span class="lineno">  298</span>&#160;        }</div><div class="line"><a name="l00299"></a><span class="lineno">  299</span>&#160;        z0 = z1;</div><div class="line"><a name="l00300"></a><span class="lineno">  300</span>&#160;    } else if (z0 != 0) {</div><div class="line"><a name="l00301"></a><span class="lineno">  301</span>&#160;        printf(&quot;no object detected, resetting tracking\n&quot;);</div><div class="line"><a name="l00302"></a><span class="lineno">  302</span>&#160;        z0 = 0;</div><div class="line"><a name="l00303"></a><span class="lineno">  303</span>&#160;        acc_dist = 0;</div><div class="line"><a name="l00304"></a><span class="lineno">  304</span>&#160;    }</div><div class="line"><a name="l00305"></a><span class="lineno">  305</span>&#160;}</div><div class="line"><a name="l00306"></a><span class="lineno">  306</span>&#160;</div><div class="line"><a name="l00307"></a><span class="lineno">  307</span>&#160;```</div></div><!-- fragment --></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="navelem"><a class="el" href="iq_8md.html">iq.md</a></li>
    <li class="footer">Generated on Mon Dec 2 2019 09:40:46 for Acconeer API by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
  </ul>
</div>
</body>
</html>
